package com.shakespace.artofandroid.chapter03.conflict

import android.content.Context
import android.util.AttributeSet
import android.util.Log
import android.view.MotionEvent
import android.view.VelocityTracker
import android.view.View
import android.view.ViewGroup
import android.widget.Scroller
import com.shakespace.firstlinecode.global.TAG

@Suppress("UNUSED_VARIABLE")
class HorizontalScrollViewEx @JvmOverloads constructor(
    context: Context?,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) :
    ViewGroup(context, attrs, defStyleAttr) {

    private var childrenSize = 0
    private var childWidth = 0
    private var childIndex = 0

    private var lastX = 0
    private var lastY = 0

    private var lastXInIntercept = 0
    private var lastYInIntercept = 0

    private val scroller = Scroller(context)
    private val velocityTracker = VelocityTracker.obtain()


    init {

    }

    override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
        var intercepted = false

        val eventX = ev.x.toInt()
        val eventY = ev.y.toInt()

        when (ev.action) {
            MotionEvent.ACTION_DOWN -> {
                intercepted = false
                /**
                 * e.g  currently  scroll in horizontal , and not finish , if user change to a Vertical move ,
                 * still do intercept
                 */
                if (!scroller.isFinished) {
                    scroller.abortAnimation()
                    intercepted = true
                }
            }

            MotionEvent.ACTION_MOVE -> {
                val deltaX = eventX - lastXInIntercept
                val deltaY = eventY - lastYInIntercept

                intercepted = Math.abs(deltaX) > Math.abs(deltaY)
            }

            MotionEvent.ACTION_UP -> {
                intercepted = false
            }
            else -> {
            }
        }

        Log.e(this.TAG, "onInterceptTouchEvent: ")

        lastX = eventX
        lastY = eventY
        lastXInIntercept = eventX
        lastYInIntercept = eventY

        return intercepted
    }

    override fun onTouchEvent(ev: MotionEvent): Boolean {

        velocityTracker.addMovement(ev)
        val eventX = ev.x.toInt()
        val eventY = ev.y.toInt()

        when (ev.action) {
            MotionEvent.ACTION_DOWN -> {
                if (!scroller.isFinished) {
                    scroller.abortAnimation()
                }
            }

            MotionEvent.ACTION_MOVE -> {
                val deltaX = eventX - lastX
                val deltaY = eventY - lastY

                scrollBy(-deltaX, 0)
            }

            MotionEvent.ACTION_UP -> {
                velocityTracker.computeCurrentVelocity(1000)
                val xVelocity = velocityTracker.xVelocity

                if (Math.abs(xVelocity) >= 50) {
                    if (xVelocity > 0) {
                        childIndex -= 1
                    } else {
                        childIndex += 1
                    }
                } else {
                    childIndex = (scrollX + childWidth / 2) / childWidth
                }
                childIndex = Math.max(0, Math.min(childIndex, childrenSize - 1))

                val dx = childIndex * childWidth - scrollX
                smoothScrollBy(dx, 0)
                velocityTracker.clear()
            }
            else -> {
            }
        }

        lastX = eventX
        lastY = eventY

        return true
    }


    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)

        val measuredWidth: Int
        val measuredHeight: Int

        measureChildren(widthMeasureSpec, heightMeasureSpec)

        val widthSpaceSize = MeasureSpec.getSize(widthMeasureSpec)
        val heightSpaceSize = MeasureSpec.getSize(heightMeasureSpec)
        val widthSpecMode = MeasureSpec.getMode(widthMeasureSpec)
        val heightSpecMode = MeasureSpec.getMode(heightMeasureSpec)

        if (childCount == 0) {
            setMeasuredDimension(0, 0)
        } else if (widthSpecMode == MeasureSpec.AT_MOST && heightSpecMode == MeasureSpec.AT_MOST) {
            val view = getChildAt(0)
            measuredWidth = view.measuredWidth * childCount
            measuredHeight = view.measuredHeight
            setMeasuredDimension(measuredWidth, measuredHeight)
        } else if (heightSpecMode == MeasureSpec.AT_MOST) {
            val view = getChildAt(0)
            measuredHeight = view.measuredHeight
            setMeasuredDimension(widthSpaceSize, measuredHeight)
        } else if (widthSpecMode == MeasureSpec.AT_MOST) {
            val view = getChildAt(0)
            measuredWidth = view.measuredWidth * childCount
            setMeasuredDimension(measuredWidth, heightSpaceSize)
        }

    }

    override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
        var childLeft = 0
        childrenSize = childCount

        for (i in 0 until childCount) {
            val view = getChildAt(i)
            if (view.visibility != View.GONE) {
                childWidth = view.measuredWidth
                view.layout(childLeft, 0, childLeft + childWidth, view.measuredHeight)
                childLeft += childWidth
            }
        }
    }


    private fun smoothScrollBy(dx: Int, i: Int) {
        scroller.startScroll(scrollX, 0, dx, 0, 500)
        invalidate()
    }

    override fun computeScroll() {
        if (scroller.computeScrollOffset()) {
            scrollTo(scroller.currX, scroller.currY)
            postInvalidate()
        }
    }

    override fun onDetachedFromWindow() {
        velocityTracker.recycle()
        super.onDetachedFromWindow()
    }

}



















